# coding=utf-8
from datetime import datetime

from flask_babel import gettext
from flask_login import login_user, current_user, login_required, logout_user

from app import application, login_manager, oid, db, models
from flask import render_template, flash, redirect, g, url_for, session, request

from app.emails import follower_notification
from app.models import User, followers, Post
from .forms import LoginForm, EditForm, PostForm, SearchForm
from config import POST_PER_PAGE, MAX_SEARCH_RESULT
from app import babel
from config import LANGUAGES


# 获取最匹配的语言
@babel.localeselector
def get_locale():
    return request.accept_languages.best_match(LANGUAGES.keys())



@login_manager.user_loader
def load_user(id):
    return User.query.get(int(id))


@application.before_request
def before_request():
    g.user = current_user
    if g.user.is_authenticated:
        g.user.last_seen = datetime.utcnow()
        db.session.add(g.user)
        db.session.commit()
        g.search_form = SearchForm()


@application.route('/', methods=['GET', 'POST'])
@application.route('/index', methods=['GET', 'POST'])
@application.route('/index/<int:page>', methods=['GET', 'POST'])
@login_required
def index(page=1):
    form = PostForm()
    # 添加一条新的博客
    if form.validate_on_submit():
        post = Post(body=form.post.data, timestamp=datetime.utcnow(), author=g.user)
        db.session.add(post)
        db.session.commit()
        flash(gettext('You post is now live!'))
        return redirect(url_for('index'))

    # 查询出用户所有的博客和关注的好友的博客
    posts = g.user.followed_posts().paginate(page, POST_PER_PAGE, False)

    # 因为index模板使用了form变量显示error信息，因此需要传form参数
    return render_template("index.html", title="Home", form=form, posts=posts)


# 登录
@application.route('/login', methods=['GET', 'POST'])
@oid.loginhandler
def login():
    if g.user is not None and g.user.is_authenticated:
        return redirect(url_for('index'))
    form = LoginForm()
    if form.validate_on_submit():
        if models.User.query.filter_by(nickname=form.openid.data).first():
            user = User.query.filter_by(nickname=form.openid.data).first_or_404()
            remember_me = False
            if 'remember_me' in session:
                remember_me = session['remember_me']
                session.pop('remember_me', None)
            login_user(user, remember=remember_me)
            return redirect(url_for('index'))

            # session['remember_me'] = form.remember_me.data
            # return oid.try_login(form.openid.data, ask_for=['nickname', 'email'])
            # flash函数显示信息
            # flash('Login requested for OpenID="' + form.openid.data + '", remember_me=' + str(form.remember_me.data))
            # flash("hello world")
    return render_template('login.html', title='Sign In',
                           form=form, providers=application.config['OPENID_PROVIDERS'])


# 登录以后的处理逻辑，openid 方式登录才会用到
@oid.after_login
def after_login(resp):
    if resp.email is None or resp.email == "":
        flash(gettext('Invalid login,please try again.'))
        return redirect(url_for('login'))
    user = User.query.filter_by(email=resp.email).first()
    if user is None:
        nickname = resp.nickname
        if nickname is None or nickname == "":
            nickname = resp.email.split('@')[0]
        # 避免出现第三方登录用户昵称出现重复导致的错误
        nickname = User.make_unique_nickname(nickname)

        user = User(nickname=nickname, email=resp.email)
        db.session.add(user)
        db.session.commit()
    remember_me = False

    if 'remember_me' in session:
        remember_me = session['remember_me']
        session.pop('remember_me', None)

    login_user(user, remember=remember_me)
    return redirect(request.args.get('next') or url_for('index'))


# 退出登录
@application.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('index'))


# 用户view
@application.route('/user/<nickname>')
@application.route('/user/<nickname>/<int:page>')
@login_required
def user(nickname, page=1):
    user = User.query.filter_by(nickname=nickname).first()

    if user is None:
        flash('User ' + nickname + ' not fount!')
        return redirect(url_for('index'))

    posts = Post.query.filter_by(user_id=user.id).paginate(page, POST_PER_PAGE, False)
    # posts = user.posts.paginate(page, POST_PER_PAGE, False)  #这种方式也可以
    return render_template('user.html', user=user, posts=posts)


# 修改用户信息
@application.route('/edit', methods=['GET', 'POST'])
@login_required
def edit():
    form = EditForm(g.user.nickname)
    if form.validate_on_submit():
        g.user.nickname = form.nickname.data
        g.user.about_me = form.about_me.data
        db.session.add(g.user)
        db.session.commit()
        flash('Your changes have been saved!')
        return redirect(url_for('index'))
    else:
        form.nickname.data = g.user.nickname
        form.about_me.data = g.user.about_me
    return render_template('edit.html', form=form)


# 定制http错误处理机制
@application.errorhandler(404)
def internal_error(error):
    return render_template('404.html'), 404


@application.errorhandler(500)
def internal_error(error):
    db.session.rollback()
    return render_template('500.html'), 500


# 关注用户
@application.route('/follow/<nickname>')
@login_required
def follow(nickname):
    user = User.query.filter_by(nickname=nickname).first()
    if user is None:
        flash('User %s not found.' % nickname)
        return redirect(url_for('index'))
    # if user == g.user:
    #     flash('You can\'t follow yourself!')
    #     return redirect(url_for('user', nickname=nickname))
    u = g.user.follow(user)
    if u is None:
        flash('Cannot follow ' + nickname + '.')
        return redirect(url_for('user', nickname=nickname))
    db.session.add(u)
    db.session.commit()
    flash('You are now following ' + nickname + '!')
    follower_notification(user, g.user)  # 发送邮件提醒有人关注你
    return redirect(url_for('user', nickname=nickname))


# 取消关注用户
@application.route('/unfollow/<nickname>')
@login_required
def unfollow(nickname):
    user = User.query.filter_by(nickname=nickname).first()
    if user is None:
        flash('User %s not found.' % nickname)
        return redirect(url_for('index'))
    # if user == g.user:
    #     flash('You can\'t unfollow yourself!')
    #     return redirect(url_for('user', nickname=nickname))
    u = g.user.unfollow(user)
    if u is None:
        flash('Cannot unfollow ' + nickname + '.')
        return redirect(url_for('user', nickname=nickname))
    db.session.add(u)
    db.session.commit()
    flash('You have stopped following ' + nickname + '.')
    return redirect(url_for('user', nickname=nickname))


@login_required
@application.route('/search', methods=['POST'])
def search():
    if not g.search_form.validate_on_submit():
        return redirect(url_for('index'))
    return redirect(url_for('search_results', query=g.search_form.search.data))


@application.route('/search_results/<query>')
@login_required
def search_results(query):
    results = Post.query.whoosh_search(query, MAX_SEARCH_RESULT).all()
    return render_template('search_results.html', query=query, results=results)


